//+------------------------------------------------------------------+
//|                                                   EA Servant.mq4 |
//|                            Dwi Malistyo <dwi.malistyo@gmail.com> |
//|                                    http://koding-ea.blogspot.com |
//+------------------------------------------------------------------+
//| Need quality and low cost EA/MT4 Script Programmer ?             | 
//| Contact my email -----------> dwi.malistyo@gmail.com             |
//+------------------------------------------------------------------+

// This EA is not created for automated trading. It only help trader
// for put TP and SL automatically when you trade manually. And this
// EA will lock profit (SL+1) and trailing the profit.


#property copyright "Dwi Malistyo <dwi.malistyo@gmail.com>"
#property link      "http://koding-ea.blogspot.com"
#include            <stderror.mqh>

extern   int      TakeProfit        =  30;
extern   int      StopLoss          =  30;
extern   int      LockPip           =  10;
extern   int      TrailingStop      =  10;
extern   bool     AllowLockPip      =  TRUE;
extern   bool     AllowTrailing     =  TRUE;

string   EAName                     = "EA Servant v1.0";
string   EACreator                  = "dwi.malistyo@gmail.com";
double   SetPoint                   =  0;

//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
//----
   SetBroker();
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
  {
//----

   Comment(  "EA Name    : ",EAName,
           "\nEA Creator  : ",EACreator,
           "\nTimeServer : ",Hour(),":",Minute()
           );
   
   
   if(OrdersOPTotal()>0)                 
   {
      GoLockingTrailing();
   }
   
//----
   return(0);
  }
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
/* Fungsi untuk set Point mengikuti broker 4 digit atau broker 5 digit*/

void SetBroker()
{
   if(Digits==3 || Digits==5)
   {
      SetPoint=Point*10;
   }
   else if(Digits==2 || Digits==4)
   {
      SetPoint=Point;
   }

}


//+------------------------------------------------------------------+
/* Fungsi untuk menghitung jumlah OP di chart yang aktif */

int OrdersOPTotal()
{
   int iTotal=0;

   for(int iCount=0;iCount<OrdersTotal();iCount++)
   {                    
        
        OrderSelect(iCount,SELECT_BY_POS,MODE_TRADES);
   
        if(OrderType()==OP_BUYSTOP && OrderSymbol()==Symbol())
        {
            iTotal++;
        }
        else if(OrderType()==OP_SELLSTOP && OrderSymbol()==Symbol())
        {
            iTotal++;
        }
        else if(OrderType()==OP_BUY && OrderSymbol()==Symbol())
        {
            iTotal++;
        }
        else if(OrderType()==OP_SELL && OrderSymbol()==Symbol())
        {
            iTotal++;
        }
        else if(OrderType()==OP_BUYLIMIT && OrderSymbol()==Symbol())
        {
            iTotal++;
        }
        else if(OrderType()==OP_SELLLIMIT && OrderSymbol()==Symbol())
        {
            iTotal++;
        }
    }             

   return(iTotal);
}


//+------------------------------------------------------------------+
/* Fungsi untuk melakukan Modifikasi OP dan menampilkan error ke Jurnal */

void OrderOPModify(int OPTicket, double OPPrice, double OPStoploss, double OPTakeProfit, datetime OPExpiration, color OPArrow_color)
{
      string Operation="";
      string sWarn="CHECK THIS ---> ";

      OrderModify(OPTicket, OPPrice, OPStoploss, OPTakeProfit, OPExpiration, OPArrow_color);
      switch(GetLastError())
      {
         case ERR_NO_ERROR                   : Print("Modify Order #"+OPTicket+" "+Operation+" SUCCESS 0 - OrderSend OK");                                     break;
         case ERR_NO_RESULT                  : Print(sWarn+"Modify Order #"+OPTicket+" "+Operation+"  ERROR 1 - No error returned, but the result is unknown"); break;
         case ERR_COMMON_ERROR               : Print(sWarn+"Modify Order #"+OPTicket+" "+Operation+"  ERROR 2 - Common error.");                                break;
         case ERR_INVALID_TRADE_PARAMETERS   : Print(sWarn+"Modify Order #"+OPTicket+" "+Operation+"  ERROR 3 - Invalid trade parameters.");                    break;
         case ERR_SERVER_BUSY                : Print(sWarn+"Modify Order #"+OPTicket+" "+Operation+"  ERROR 4 - Trade server is busy.");                        break;
         
         case ERR_OLD_VERSION                : Print(sWarn+"Modify Order #"+OPTicket+" "+Operation+"  ERROR 5 - Old version of the client terminal.");          break;
         case ERR_NO_CONNECTION              : Print(sWarn+"Modify Order #"+OPTicket+" "+Operation+"  ERROR 6 - Common error.");                                break;
         case ERR_NOT_ENOUGH_RIGHTS          : Print(sWarn+"Modify Order #"+OPTicket+" "+Operation+"  ERROR 7 - Not enough rights..");                          break;
         case ERR_TOO_FREQUENT_REQUESTS      : Print(sWarn+"Modify Order #"+OPTicket+" "+Operation+"  ERROR 8 - Too frequent requests.");                       break;
         case ERR_MALFUNCTIONAL_TRADE        : Print(sWarn+"Modify Order #"+OPTicket+" "+Operation+"  ERROR 9 - Malfunctional trade operation.");               break;
         
         case ERR_ACCOUNT_DISABLED           : Print(sWarn+"Modify Order #"+OPTicket+" "+Operation+"  ERROR 64 - Account disabled.");                           break;
         case ERR_INVALID_ACCOUNT            : Print(sWarn+"Modify Order #"+OPTicket+" "+Operation+"  ERROR 65 - Invalid account.");                            break;
         case ERR_TRADE_TIMEOUT              : Print(sWarn+"Modify Order #"+OPTicket+" "+Operation+"  ERROR 128 - Trade timeout.");                             break;
         case ERR_INVALID_PRICE              : Print(sWarn+"Modify Order #"+OPTicket+" "+Operation+"  ERROR 129 - Invalid price.");                             break;
         case ERR_INVALID_STOPS              : Print(sWarn+"Modify Order #"+OPTicket+" "+Operation+"  ERROR 130 - Invalid stops. - OR need more BALANCE");      break;
         
         case ERR_INVALID_TRADE_VOLUME       : Print(sWarn+"Modify Order #"+OPTicket+" "+Operation+"  ERROR 131 - Invalid trade volume.");                      break;
         case ERR_MARKET_CLOSED              : Print(sWarn+"Modify Order #"+OPTicket+" "+Operation+"  ERROR 132 - Market is closed.");                          break;
         case ERR_TRADE_DISABLED             : Print(sWarn+"Modify Order #"+OPTicket+" "+Operation+"  ERROR 133 - Trade is disabled.");                         break;
         case ERR_NOT_ENOUGH_MONEY           : Print(sWarn+"Modify Order #"+OPTicket+" "+Operation+"  ERROR 134 - Not enough money.");                          break;
         case ERR_PRICE_CHANGED              : Print(sWarn+"Modify Order #"+OPTicket+" "+Operation+"  ERROR 135 - Price changed.");                             break;
         
         case ERR_OFF_QUOTES                 : Print(sWarn+"Modify Order #"+OPTicket+" "+Operation+"  ERROR 136 - Off quotes.");                                break;
         case ERR_BROKER_BUSY                : Print(sWarn+"Modify Order #"+OPTicket+" "+Operation+"  ERROR 137 - Broker is busy.");                            break;
         case ERR_REQUOTE                    : Print(sWarn+"Modify Order #"+OPTicket+" "+Operation+"  ERROR 138 - Requote.");                                   break;
         case ERR_ORDER_LOCKED               : Print(sWarn+"Modify Order #"+OPTicket+" "+Operation+"  ERROR 139 - Order is locked.");                           break;
         case ERR_LONG_POSITIONS_ONLY_ALLOWED: Print(sWarn+"Modify Order #"+OPTicket+" "+Operation+"  ERROR 140 - Long positions only allowed.");               break;
         
         case ERR_TOO_MANY_REQUESTS          : Print(sWarn+"Modify Order #"+OPTicket+" "+Operation+"  ERROR 141 - Too many requests.");                         break;
         case ERR_TRADE_MODIFY_DENIED        : Print(sWarn+"Modify Order #"+OPTicket+" "+Operation+"  ERROR 145 - Modification denied because order too close to market.");                               break;
         case ERR_TRADE_CONTEXT_BUSY         : Print(sWarn+"Modify Order #"+OPTicket+" "+Operation+"  ERROR 146 - Trade context is busy.");                     break;
         case ERR_TRADE_EXPIRATION_DENIED    : Print(sWarn+"Modify Order #"+OPTicket+" "+Operation+"  ERROR 147 - Expirations are denied by broker.");          break;
         case ERR_TRADE_TOO_MANY_ORDERS      : Print(sWarn+"Modify Order #"+OPTicket+" "+Operation+"  ERROR 148 - The amount of open and pending orders has reached the limit set by the broker.");       break;
         
         case ERR_TRADE_HEDGE_PROHIBITED     : Print(sWarn+"Modify Order #"+OPTicket+" "+Operation+"  ERROR 149 - An attempt to open a position opposite to the existing one when hedging is disabled."); break;
         case ERR_TRADE_PROHIBITED_BY_FIFO   : Print(sWarn+"Modify Order #"+OPTicket+" "+Operation+"  ERROR 150 - An attempt to close a position contravening the FIFO rule.");                           break;
         
         default: break;
      }
}


//+------------------------------------------------------------------+
/* Fungsi untuk mengunci (Lock) dan Trailing */
void GoLockingTrailing()
{
  
   for(int iTrade=0;iTrade<OrdersTotal();iTrade++)
   {

      OrderSelect(iTrade,SELECT_BY_POS,MODE_TRADES);                         
      
      if(OrderType()==OP_BUY && OrderSymbol()==Symbol())
      {
      
        //Pasang SL dan TP jika belum ada sebelumnya.
        if(OrderStopLoss()==0 && OrderTakeProfit()==0)
        {
                  OrderModify(OrderTicket(),OrderOpenPrice(),OrderOpenPrice()-StopLoss*SetPoint,OrderOpenPrice()+TakeProfit*SetPoint,0,CLR_NONE);
                  return(0);            
        }  
        else if(OrderStopLoss()==0 && OrderTakeProfit()!=0)
        {
                  OrderModify(OrderTicket(),OrderOpenPrice(),OrderOpenPrice()-StopLoss*SetPoint,OrderTakeProfit(),0,CLR_NONE);
                  return(0);            
        }
        else if(OrderTakeProfit()==0 && OrderStopLoss()!=0)
        {
                  OrderModify(OrderTicket(),OrderOpenPrice(),OrderStopLoss(),OrderOpenPrice()+TakeProfit*SetPoint,0,CLR_NONE);
                  return(0);              
        }
      
        if(OrderStopLoss()<OrderOpenPrice() || OrderStopLoss()==0)
        {
      
          if(AllowLockPip==TRUE)
          {
               
              if(Bid-OrderOpenPrice()>=LockPip*SetPoint && OrderStopLoss()!=OrderOpenPrice()+1*SetPoint)
               {
                  OrderOPModify(OrderTicket(),OrderOpenPrice(),OrderOpenPrice()+1*SetPoint,OrderTakeProfit(),0,CLR_NONE);
                  return(0);            
               }
           } 
        }
        else if(OrderStopLoss()>OrderOpenPrice())
        {
            
                 if(Bid-OrderStopLoss()>SetPoint*TrailingStop)
                 {
                     if(AllowTrailing==TRUE)
                     {
                        OrderOPModify(OrderTicket(),OrderOpenPrice(),Bid-SetPoint*TrailingStop,OrderTakeProfit(),0,CLR_NONE);
                        return(0);                    
                     }
                 }
         
        }
      }
      else if(OrderType()==OP_SELL && OrderSymbol()==Symbol())
      {      

        //Pasang SL dan TP jika belum ada sebelumnya.
        if(OrderStopLoss()==0 && OrderTakeProfit()==0)
        {
                  OrderModify(OrderTicket(),OrderOpenPrice(),OrderOpenPrice()+StopLoss*SetPoint,OrderOpenPrice()-TakeProfit*SetPoint,0,CLR_NONE);
                  return(0);            
        }  
        else if(OrderStopLoss()==0 && OrderTakeProfit()!=0)
        {
                  OrderModify(OrderTicket(),OrderOpenPrice(),OrderOpenPrice()+StopLoss*SetPoint,OrderTakeProfit(),0,CLR_NONE);
                  return(0);            
        }
        else if(OrderTakeProfit()==0 && OrderStopLoss()!=0)
        {
                  OrderModify(OrderTicket(),OrderOpenPrice(),OrderStopLoss(),OrderOpenPrice()-TakeProfit*SetPoint,0,CLR_NONE);
                  return(0);              
        }
      

        if(OrderStopLoss()>OrderOpenPrice() || OrderStopLoss()==0)
        {
        
 
          if(AllowLockPip==TRUE)
          {
           if(OrderOpenPrice()-Ask>=LockPip*SetPoint && OrderStopLoss()!=OrderOpenPrice()-1*SetPoint)
           {
               OrderOPModify(OrderTicket(),OrderOpenPrice(),OrderOpenPrice()-1*SetPoint,OrderTakeProfit(),0,CLR_NONE);
               return(0);
           }
          }

        }
        else if(OrderStopLoss()<OrderOpenPrice())
        {
               if((OrderStopLoss()-Ask)>(SetPoint*TrailingStop))
               {
                     if(AllowTrailing==TRUE)
                     {
                        OrderOPModify(OrderTicket(),OrderOpenPrice(),Ask+SetPoint*TrailingStop,OrderTakeProfit(),0,CLR_NONE);
                        return(0);
                     }
               }
                 
         }
      }
   }   

}

